home *** CD-ROM | disk | FTP | other *** search
/ Computer Select (Limited Edition) / Computer Select.iso / msj / v06n06 / intnat.exe / KEY.EXE / KEYMAPCH.C < prev    next >
Encoding:
C/C++ Source or Header  |  1991-11-01  |  7.9 KB  |  283 lines

  1. /* 
  2.  * KEYMAP child window segment
  3.  * Copyright (c) 1991 by Peter Belew and Bill Hall
  4.  */
  5.  
  6. #define NOCOMM
  7. #define NOKANJI
  8. #define NOATOM
  9. #define NOSOUND
  10. #include <windows.h>
  11. #include <string.h>
  12. #include "keymap.h"
  13. #include "winutils.h"
  14.  
  15. /* local functions */
  16. static void NEAR KeyWndPaint(HWND hWnd, HDC hDC);
  17. static int NEAR FindIndex(int sc);
  18. static void NEAR DoKeyStroke(HWND hWnd, BOOL down);
  19.    
  20. /* All messages for key windows are processed here */
  21. long FAR PASCAL KeyWndProc(register HWND hWnd, unsigned message,
  22.                register WORD wParam, LONG lParam)
  23. {
  24.  
  25.     PAINTSTRUCT ps;
  26.  
  27.     switch(message) {
  28.  
  29.     case WM_LBUTTONDOWN:    /* simulate keydown with mouse */
  30.         SetCapture(hWnd);
  31.         DoKeyStroke(hWnd, TRUE);
  32.         break;
  33.  
  34.     case WM_LBUTTONUP:    /* simulate keyup with mouse */
  35.         if (hWnd == GetCapture()) {
  36.             DoKeyStroke(hWnd, FALSE);
  37.         ReleaseCapture();
  38.         }
  39.         break;
  40.  
  41.     case WM_CREATE:
  42.         ChildCreate(hWnd); /* initialize kdata structure */
  43.         break;
  44.  
  45.     case WM_PAINT:        /* redraw a key window */
  46.         BeginPaint(hWnd, &ps);
  47.         KeyWndPaint(hWnd, ps.hdc);
  48.         EndPaint(hWnd, &ps);
  49.         break;
  50.  
  51.     default:
  52.         return ((long)DefWindowProc(hWnd,message,wParam,lParam));
  53.         break;
  54.     }
  55.     return(0L);
  56. }
  57.  
  58. /* simulate a keystroke */
  59. static void NEAR DoKeyStroke(HWND hWnd, BOOL down)
  60. {
  61.     WORD sc, vk;    /* scan code, virtual key code */
  62.     WORD factor;
  63.     BYTE buf[4];
  64.     BYTE kstate[256];
  65.     int result;
  66.  
  67.     sc = GetWindowWord(hWnd, GWW_ID);
  68.     vk = MapVirtualKey(sc, 1);
  69.     factor = down ? 0 : 0x8000;
  70.  
  71.     if (down) {
  72.         SendMessage(hEdit,WM_KEYDOWN,vk,MAKELONG(1, sc + factor));
  73.     memset(kstate, 0, sizeof(kstate));
  74.     if (GetKeyState(VK_SHIFT) & 0x8000)
  75.         kstate[VK_SHIFT] = 0x80;
  76.     if (GetKeyState(VK_CONTROL) & 0x8000)
  77.         kstate[VK_CONTROL] = 0x80;
  78.     if (GetKeyState(VK_MENU) & 0x8000)
  79.         kstate[VK_MENU] = 0x80;
  80.     if (GetKeyState(VK_CAPITAL) & 1)
  81.         kstate[VK_CAPITAL] = 1;
  82.     result = ToAscii(vk, sc, kstate, buf, 0);
  83.     if (result == 1)
  84.             SendMessage(hEdit,WM_CHAR,buf[0],MAKELONG(1,sc+factor));
  85.     else if (result == 2) {
  86.             SendMessage(hEdit,WM_CHAR,buf[0],MAKELONG(1,sc+factor));
  87.             SendMessage(hEdit,WM_CHAR,buf[2],MAKELONG(1,sc+factor));
  88.     }
  89.     }
  90.     else
  91.         SendMessage(hEdit,WM_KEYUP,vk,MAKELONG(1,sc+factor));
  92. }
  93.  
  94. /* fill out the kdata structure for each key */
  95. void FAR ChildCreate(HWND hWnd)
  96. {
  97.     WORD vk;        /* virtual key code */
  98.     int id;        /* key window id */
  99.     int i;
  100.     char kbuf[256];    /* current keyboard state */
  101.     char cbuf[4];    /* character buffer */
  102.     int result;
  103.     WORD spcscan;
  104.  
  105.     spcscan = MapVirtualKey(VK_SPACE,0); /* read space scancode */
  106.     memset(kbuf,0,sizeof(kbuf));    /* all keys up */
  107.     id = GetWindowWord(hWnd, GWW_ID);    /* get the window number */
  108.     vk = MapVirtualKey(id, 1);    /* find the associated virtual key */
  109.     i = FindIndex(id);        /* get the kdata index */
  110.   /* clear the buffers */
  111.     memset(kdata[i].top, 0, sizeof(kdata[i].top));
  112.     memset(kdata[i].bottom, 0, sizeof(kdata[i].bottom));
  113.     kdata[i].caps = 0;
  114.  
  115.   /* clear any pending dead keys */
  116.     ToAscii(VK_SPACE, spcscan, kbuf, cbuf, 0);
  117.  
  118.     result = ToAscii(vk, id, kbuf, cbuf, 0);  /* unshifted */
  119.     if (result == 2)
  120.         kdata[i].bottom[0] = cbuf[2];    /* store correct value */
  121.     else if (result == 1)
  122.         kdata[i].bottom[0] = cbuf[0];
  123.     else if (result < 0) {
  124.         kdata[i].bottom[0] = cbuf[0];    /* dead key */
  125.         ToAscii(VK_SPACE,spcscan,kbuf,cbuf,0);     /* clear dead key */
  126.     }
  127.  
  128.     kbuf[VK_CAPITAL] = 1;   /* repeat the above for lock table */
  129.     result = ToAscii(vk, id, kbuf, cbuf, 0);
  130.     if (result == 2)
  131.         kdata[i].caps = cbuf[2];
  132.     else if (result == 1)
  133.         kdata[i].caps = cbuf[0];
  134.     else if (result < 0) {
  135.         kdata[i].caps = cbuf[0];
  136.         ToAscii(VK_SPACE,spcscan,kbuf,cbuf,0);
  137.     }
  138.     kbuf[VK_CAPITAL] = 0;
  139.  
  140.     kbuf[VK_SHIFT] = 0x80; /* repeat the above with shift key down */
  141.     kbuf[VK_CONTROL] = 0;
  142.     result = ToAscii(vk, id, kbuf, cbuf, 0);
  143.     if (result == 2)
  144.     kdata[i].top[0] = cbuf[2];
  145.     else if (result == 1)
  146.     kdata[i].top[0] = cbuf[0];
  147.     else if (result < 0) {
  148.     kdata[i].top[0] = cbuf[0];
  149.         ToAscii(VK_SPACE, spcscan, kbuf, cbuf, 0);
  150.     }
  151.  
  152.     kbuf[VK_MENU] = 0x80; /* do the same with CTRL-ALT (Alt-gr) */
  153.     kbuf[VK_SHIFT] = 0;
  154.     kbuf[VK_CONTROL] = 0x80;
  155.     result = ToAscii(vk, id, kbuf, cbuf, 0);
  156.     if (result == 2)
  157.     kdata[i].bottom[1] = cbuf[2];
  158.     else if (result == 1)
  159.     kdata[i].bottom[1] = cbuf[0];
  160.     else if (result < 0) {
  161.     kdata[i].bottom[1] = cbuf[0];
  162.         kbuf[VK_MENU] = 0;
  163.         ToAscii(VK_SPACE, spcscan, kbuf, cbuf, 0);
  164.     }
  165.     
  166.     kbuf[VK_MENU] = 0x80;    /* finally repeat for Shift CTRL-ALT */
  167.     kbuf[VK_SHIFT] = 0x80;
  168.     kbuf[VK_CONTROL] = 0x80;
  169.     result = ToAscii(vk, id, kbuf, cbuf, 0);
  170.     if (result == 2)
  171.     kdata[i].top[1] = cbuf[2];
  172.     else if (result == 1)
  173.     kdata[i].top[1] = cbuf[0];
  174.     else if (result < 0) {
  175.     kdata[i].top[1] = cbuf[0];
  176.         kbuf[VK_MENU] = 0;
  177.         ToAscii(VK_SPACE, spcscan, kbuf, cbuf, 0);
  178.     }
  179.     /* do some filtering to simplify the display
  180.        but results may depend on language module */
  181.  
  182.     if ('A' <= vk && vk <= 'Z') /* letters, don't show lower case */
  183.     kdata[i].bottom[0] = 0;
  184.   /* also if in caps table and is a letter, don't show lower case */
  185.     else if (IsCharAlpha(kdata[i].caps)
  186.          && (kdata[i].top[0] == kdata[i].caps))
  187.     kdata[i].bottom[0] = 0;
  188.   /* don't repeat duplicates on SHIFT-ALT-gr entries */
  189.     if (AnsiLower(MAKEINTRESOURCE(kdata[i].top[1])) == 
  190.     AnsiLower(MAKEINTRESOURCE(kdata[i].bottom[1]))) {
  191.     kdata[i].bottom[1] = kdata[i].top[1];
  192.     kdata[i].top[1] = 0;
  193.     }
  194. }
  195.  
  196. /* draw a key window */
  197. static void NEAR KeyWndPaint(HWND hWnd, HDC hDC)
  198. {
  199.  
  200.     RECT rect;
  201.     int i;
  202.     int x,y;
  203.     WORD sc;
  204.  
  205.     sc = GetWindowWord(hWnd, GWW_ID);  /* get id of window to draw */
  206.     i = FindIndex(sc);
  207.     GetClientRect(hWnd, &rect);
  208.  
  209.     if (invert) {    /* invert the key  window */
  210.     SelectObject(hDC, GetStockObject(BLACK_BRUSH));
  211.     SetTextColor(hDC, 0xffffff);
  212.     }
  213.     else
  214.     if (KeyColor == IDM_GRAY)    /* draw normally */
  215.             SelectObject(hDC, GetStockObject(LTGRAY_BRUSH));
  216.  
  217.     SetBkMode(hDC, TRANSPARENT);
  218.  
  219.     /* draw the outline */
  220.     RoundRect(hDC, rect.left, rect.top, rect.right, rect.bottom,
  221.            rect.right / 8, rect.bottom / 8);
  222.  
  223.     x = 2 * cxborder;
  224.     y = cyborder;
  225.     if (kdata[i].top[0])
  226.        TextOut(hDC, x, y, &kdata[i].top[0], 1);
  227.     if (kdata[i].top[1])
  228.         TextOut(hDC, rect.right / 2, y, &kdata[i].top[1], 1);
  229.     y += cheight + cyborder;
  230.     if (kdata[i].bottom[0])
  231.         TextOut(hDC, x, y, &kdata[i].bottom[0], 1);
  232.     if (kdata[i].bottom[1])
  233.         TextOut(hDC, rect.right / 2, y, &kdata[i].bottom[1], 1);
  234.  
  235. }
  236.  
  237. /* find the kdata structure corresponding to a given window index */
  238. static int NEAR FindIndex(int sc)
  239. {
  240.     register int i;
  241.  
  242.     for (i = 0; i < MAXKEYS; i++)
  243.     if (sc == kdata[i].scancode)
  244.         break;
  245.  
  246.     return i;
  247. }
  248.  
  249. /* subclass the edit window in order to invert the keymap */
  250. LONG FAR PASCAL LocalEditWndProc(register HWND hWnd,unsigned message,
  251.                       register WORD wParam,LONG lParam)
  252. {
  253.  
  254.     WORD sc;
  255.     HWND hMain;
  256.     HWND hctl;
  257.     BOOL down;
  258.  
  259.     switch(message) {
  260.  
  261.     case WM_KEYDOWN:
  262.         down = TRUE;
  263.         goto keyup;
  264.  
  265.     case WM_KEYUP:
  266.         down = FALSE;
  267. keyup:
  268.         sc = LOBYTE(HIWORD(lParam)); /* get key window number */
  269.         hMain = GetWindowWord(hWnd, GWW_HWNDPARENT);
  270.         hctl = GetDlgItem(hMain, sc);    /* and the handle */
  271.         if (hctl) {
  272.         invert = down ? TRUE : FALSE;
  273.             InvalidateRect(hctl, NULL, TRUE); /* redraw */
  274.         UpdateWindow(hctl);
  275.         } /* return everything to edit wnd proc */
  276.  
  277.     default:
  278.         return(CallWindowProc(fpEditWndProc,hWnd,
  279.                   message,wParam,lParam));
  280.     }
  281.     return 0L;
  282. }
  283.